Sort Subroutine

private subroutine Sort(input, flag)

Subroutine to sort a vector of points using the Heap-sort algorithm. Data are sorted by value if flag =1, or by separation distance if flag = 0. Actually, only a pointer is sorted, as this is more efficient. Subroutine Adapted from Numerical Recipes in Fortran 90: Press, Teukolsky, Vetterling and Flannery (1996) pg. 1171

Arguments

Type IntentOptional Attributes Name
type(site), intent(inout), DIMENSION(:) :: input
integer, intent(in) :: flag

Variables

Type Visibility Attributes Name Initial
type(site), public :: dummy
integer, public :: i
integer, public :: n
type(site), public, DIMENSION(:), POINTER :: work

Subroutines

subroutine sift_down(l, r, flag)

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: l
integer, intent(in) :: r
integer, intent(in) :: flag

Source Code

SUBROUTINE Sort &
!
(input, flag)
	
IMPLICIT NONE
	
!Arguments with intent(in):
INTEGER,INTENT(in) :: flag

!Arguments with intent(inout) 
TYPE(site), DIMENSION(:), INTENT(inout) :: input

	
!Local variable declarations
INTEGER :: i,n
TYPE(site), DIMENSION(:), POINTER :: work
TYPE(site) :: dummy
!----------------------------------end of declarations-------------------------
	
n=SIZE(input)
ALLOCATE(work(n))
work=input

DO i=n/2,1,-1
	!Loop down the left range of the sift-down: The element to be sifted
	!is decremented to n/2 to 1 during "Hiring" in heap creation
	CALL sift_down(i,n,flag)
END DO

DO i=n,2,-1
	!Loop down the right range of the sift-down: Decremented from n-1 to
	!1 during the "Retirement and promotion" stage of heap creation
		
	!Clear space at the top of the array and retire the top of the heap into it
	dummy=work(1)
	work(1)=work(i)
	work(i)=dummy

	CALL sift_down(1,i-1,flag)
END DO

input=work

DEALLOCATE (work)

CONTAINS

SUBROUTINE sift_down(l,r,flag)
	IMPLICIT NONE
	!Dummy argument declaration
	INTEGER,INTENT(in) :: l,r,flag
	
	!Local variable declarations
	INTEGER :: j,old
	Type(site) :: a
	
	!Carry out sift-down on element array(l) to maintain heap structure
		
	!Get element to sift
	a=work(l)
	old=l
	j=l+l
		
	SELECT CASE(flag)

	CASE(0)
		!If flag = 0, sort by h
		!Do while j<=r
		DO
			IF(j>r) EXIT
			IF(j<r) THEN
				!Compare to the better underling
				IF(work(j)%h<work(j+1)%h) j=j+1
			END IF

			!If found a's level, terminate the sift-down, else demote and continue
			IF(a%h >= work(j)%h) EXIT
			work(old) = work(j)
			old=j
			j=j+j
		END DO
		
	CASE(1)
		!If flag = 1, sort by value
		!Do while j<=r
		DO
			IF(j>r) EXIT
			IF(j<r) THEN
				!Compare to the better underling
				IF(work(j)%value<work(j+1)%value) j=j+1
			END IF

			!If found a's level, terminate the sift-down, else demote and continue
			IF(a%value >= work(j)%value) EXIT
			work(old) = work(j)
			old=j
			j=j+j
		END DO
		
	END SELECT

	!Put into its slot
	work(old)=a
END SUBROUTINE sift_down

END SUBROUTINE Sort